home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / new_file / mintprgs / mint112s / mint112s.lzh / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-30  |  12.9 KB  |  650 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992,1993 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /*
  8.  * misc. utility routines
  9.  */
  10.  
  11. #include "mint.h"
  12.  
  13. /*
  14.  * given an address, find the corresponding memory region in this program's
  15.  * memory map
  16.  */
  17.  
  18. MEMREGION *
  19. addr2mem(a)
  20.     virtaddr a;
  21. {
  22.     int i;
  23.  
  24.     for (i = 0; i < curproc->num_reg; i++) {
  25.         if (a == curproc->addr[i])
  26.             return curproc->mem[i];
  27.     }
  28.     return 0;
  29. }
  30.  
  31. /*
  32.  * given a pid, return the corresponding process
  33.  */
  34.  
  35. PROC *
  36. pid2proc(pid)
  37.     int pid;
  38. {
  39.     PROC *p;
  40.  
  41.     for (p = proclist; p; p = p->gl_next) {
  42.         if (p->pid == pid)
  43.             return p;
  44.     }
  45.     return 0;
  46. }
  47.  
  48. /*
  49.  * return a new pid
  50.  */
  51.  
  52. int
  53. newpid()
  54. {
  55.     static int _maxpid = 1;
  56.     int i;
  57. #ifndef NDEBUG
  58.     int j = 0;
  59. #endif
  60.  
  61.     do {
  62.         i = _maxpid++;
  63.         if (_maxpid >= 1000) _maxpid = 1;
  64.         assert(j++ < 1000);
  65.     } while (pid2proc(i));
  66.  
  67.     return i;
  68. }
  69.  
  70. /*
  71.  * zero out a block of memory, quickly; the block must be word-aligned,
  72.  * and should be long-aligned for speed reasons
  73.  */
  74.  
  75. void
  76. zero(place, size)
  77.     char *place;
  78.     long size;
  79. {
  80.     long cruft;
  81.     long blocksize;
  82.  
  83.     cruft = size % 256;    /* quickzero does 256 byte blocks */
  84.     blocksize = size/256;    /* divide by 256 */
  85.     if (blocksize > 0) {
  86.         quickzero(place, blocksize);
  87.         place += (blocksize*256);
  88.     }
  89.     while (cruft > 0) {
  90.         *place++ = 0;
  91.         cruft--;
  92.     }
  93. }
  94.  
  95. #ifdef JUNK_MEM
  96. void
  97. fillwjunk(place, size)
  98.     long *place;
  99.     long size;
  100. {
  101.     while (size > 0) {
  102.         *place++ = size;
  103.         size -= 4;
  104.     }
  105. }
  106. #endif
  107.  
  108. /*
  109.  * kernel memory allocation routines
  110.  */
  111.  
  112. #define KERMEM_THRESHOLD (QUANTUM-8)
  113. #if 0
  114. #define KERMEM_SIZE QUANTUM
  115. #else
  116. #define KERMEM_SIZE ((KERMEM_THRESHOLD+8)*2)
  117. #endif
  118. #define KMAGIC ((MEMREGION *)0x87654321L)
  119. #define NKMAGIC 0x19870425L
  120.  
  121. void * ARGS_ON_STACK 
  122. kmalloc(size)
  123.     long size;
  124. {
  125.     MEMREGION *m;
  126.     MEMREGION **p;
  127.     long *lp;
  128.  
  129.     /*
  130.      * increase size by two pointers' worth: the first contains
  131.      * a pointer to the region descriptor for this block, and the
  132.      * second contains KMAGIC.  If the block came from nalloc,
  133.      * then they both contain NKMAGIC.
  134.      */
  135.     size += sizeof(m) + sizeof(m);
  136. /*
  137.  * for small requests, we use nalloc first
  138.  */
  139. tryagain:
  140.     if (size < KERMEM_THRESHOLD) {
  141.         lp = nalloc(size);
  142.         if (lp) {
  143.         *lp++ = NKMAGIC;
  144.         *lp++ = NKMAGIC;
  145.         TRACELOW(("kmalloc(%lx) -> (nalloc) %lx",size,lp));
  146.         return lp;
  147.         }
  148.         else {
  149.         DEBUG(("kmalloc(%lx): nalloc is out of memory",size));
  150.  
  151.     /* If this is commented out, then we fall through to try_getregion */
  152.         if (0 == (m = get_region(alt, KERMEM_SIZE, PROT_S))) {
  153.             if (0 == (m = get_region(core, KERMEM_SIZE, PROT_S))) {
  154.             DEBUG(("No memory for another arena"));
  155.             goto try_getregion;
  156.             }
  157.         }
  158.         lp = (long *)m->loc;
  159.         *lp++ = (long)KMAGIC;
  160.         *lp++ = (long)m;
  161.         nalloc_arena_add((void *)lp,KERMEM_SIZE - 2*SIZEOF(long));
  162.         goto tryagain;
  163.         }
  164.     }
  165.  
  166. try_getregion:
  167.     m = get_region(alt, size, PROT_S);
  168.  
  169.     if (!m) m = get_region(core, size, PROT_S);
  170.  
  171.     if (m) {
  172.         p = (MEMREGION **)m->loc;
  173.         *p++ = KMAGIC;
  174.         *p++ = m;
  175.         TRACELOW(("kmalloc(%lx) -> (get_region) %lx",size,p));
  176.         return (void *)p;
  177.     }
  178.     else {
  179.         TRACELOW(("kmalloc(%lx) -> (fail)",size));
  180. #if 0
  181.         /* this is a serious offense; I want to hear about it */
  182.         /* maybe Allan wanted to hear about it, but ordinary users
  183.          * won't! -- ERS
  184.          */
  185.         NALLOC_DUMP();
  186.         BIG_MEM_DUMP(0,0);
  187. #endif
  188.         return 0;
  189.     }
  190. }
  191.  
  192. /* allocate from ST memory only */
  193.  
  194. void *
  195. kcore(size)
  196.     long size;
  197. {
  198.     MEMREGION *m;
  199.     MEMREGION **p;
  200.  
  201.     size += sizeof(m) + sizeof (m);
  202.     m = get_region(core, size, PROT_S);
  203.  
  204.     if (m) {
  205.         p = (MEMREGION **)m->loc;
  206.         *p++ = KMAGIC;
  207.         *p++ = m;
  208.         return (void *)p;
  209.     }
  210.     else {
  211.         return 0;
  212.     }
  213. }
  214.  
  215. void ARGS_ON_STACK 
  216. kfree(place)
  217.     void *place;
  218. {
  219.     MEMREGION **p;
  220.     MEMREGION *m;
  221.  
  222.     TRACELOW(("kfree(%lx)",place));
  223.  
  224.     if (!place) return;
  225.     p = place;
  226.     p -= 2;
  227.     if (*p == (MEMREGION *)NKMAGIC) {
  228.         nfree(p);
  229.         return;
  230.     }
  231.     else if (*p++ != KMAGIC) {
  232.         FATAL("kfree: memory not allocated by kmalloc");
  233.     }
  234.     m = *p;
  235.     if (--m->links != 0) {
  236.         FATAL("kfree: block has %d links", m->links);
  237.     }
  238.     free_region(m);
  239. }
  240.  
  241. /*
  242.  * "user" memory allocation routines; the kernel can use these to
  243.  * allocate/free memory that will be attached in some way to a process
  244.  * (and freed automatically when the process exits)
  245.  */
  246. void * ARGS_ON_STACK 
  247. umalloc(size)
  248.     long size;
  249. {
  250.     return (void *)m_xalloc(size, 3);
  251. }
  252.  
  253. void ARGS_ON_STACK 
  254. ufree(block)
  255.     void *block;
  256. {
  257.     (void)m_free((virtaddr)block);
  258. }
  259.  
  260. /*
  261.  * convert a time in milliseconds to a GEMDOS style date/time
  262.  * timeptr[0] gets the time, timeptr[1] the date.
  263.  * BUG/FEATURE: in the conversion, it is assumed that all months have
  264.  * 30 days and all years have 360 days.
  265.  */
  266.  
  267. void ARGS_ON_STACK 
  268. ms_time(ms, timeptr)
  269.     ulong ms;
  270.     short *timeptr;
  271. {
  272.     ulong secs;
  273.     short tsec, tmin, thour;
  274.     short tday, tmonth, tyear;
  275.  
  276.     secs = ms / 1000;
  277.     tsec = secs % 60;
  278.     secs /= 60;        /* secs now contains # of minutes */
  279.     tmin = secs % 60;
  280.     secs /= 60;        /* secs now contains # of hours */
  281.     thour = secs % 24;
  282.     secs /= 24;        /* secs now contains # of days */
  283.     tday = secs % 30;
  284.     secs /= 30;
  285.     tmonth = secs % 12;
  286.     tyear = secs / 12;
  287.     *timeptr++ = (thour << 11) | (tmin << 5) | (tsec >> 1);
  288.     *timeptr = (tyear << 9) | ((tmonth + 1) << 5) | (tday+1);
  289. }
  290.  
  291. /*
  292.  * unixtim(time, date): convert a Dos style (time, date) pair into
  293.  * a Unix time (seconds from midnight Jan 1., 1970)
  294.  */
  295.  
  296. static int const
  297. mth_start[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
  298.  
  299. long ARGS_ON_STACK 
  300. unixtim(time, date)
  301.     unsigned time, date;
  302. {
  303.     int sec, min, hour;
  304.     int mday, mon, year;
  305.     long y, s;
  306.  
  307.     sec = (time & 31) << 1;
  308.     min = (time >> 5) & 63;
  309.     hour = (time >> 11) & 31;
  310.     mday = date & 31;
  311.     mon = ((date >> 5) & 15) - 1;
  312.     year = 80 + ((date >> 9) & 255);
  313.  
  314. /* calculate tm_yday here */
  315.     y = (mday - 1) + mth_start[mon] + /* leap year correction */
  316.         ( ( (year % 4) != 0 ) ? 0 : (mon > 1) );
  317.  
  318.     s = (sec) + (min * 60L) + (hour * 3600L) +
  319.         (y * 86400L) + ((year - 70) * 31536000L) +
  320.         ((year - 69)/4) * 86400L;
  321.  
  322.     return s;
  323. }
  324.  
  325. /* convert a Unix time into a DOS time. The longword returned contains
  326.    the time word first, then the date word.
  327.    BUG: we completely ignore any time zone information.
  328. */
  329. #define SECS_PER_MIN    (60L)
  330. #define SECS_PER_HOUR   (3600L)
  331. #define SECS_PER_DAY    (86400L)
  332. #define SECS_PER_YEAR   (31536000L)
  333. #define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
  334.  
  335. static int
  336. days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  337.  
  338. long ARGS_ON_STACK 
  339. dostim(t)
  340.     long t;
  341. {
  342.         unsigned long time, date;
  343.     int tm_hour, tm_min, tm_sec;
  344.     int tm_year, tm_mon, tm_mday;
  345.     int i;
  346.  
  347.     if (t <= 0) return 0;
  348.  
  349.     tm_year = 70;
  350.     while (t >= SECS_PER_YEAR) {
  351.         if ((tm_year & 0x3) == 0) {
  352.             if (t < SECS_PER_LEAPYEAR)
  353.                 break;
  354.             t -= SECS_PER_LEAPYEAR;
  355.         } else {
  356.             t -= SECS_PER_YEAR;
  357.         }
  358.         tm_year++;
  359.     }
  360.     tm_mday = (int)(t/SECS_PER_DAY);
  361.         days_per_mth[1] = (tm_year & 0x3) ? 28 : 29;
  362.         for (i = 0; tm_mday >= days_per_mth[i]; i++)
  363.                 tm_mday -= days_per_mth[i];
  364.         tm_mon = i+1;
  365.     tm_mday++;
  366.         t = t % SECS_PER_DAY;
  367.         tm_hour = (int)(t/SECS_PER_HOUR);
  368.         t = t % SECS_PER_HOUR;
  369.         tm_min = (int)(t/SECS_PER_MIN);
  370.         tm_sec = (int)(t % SECS_PER_MIN);
  371.  
  372.     if (tm_year < 80) {
  373.         tm_year = 80;
  374.         tm_mon = tm_mday = 1;
  375.         tm_hour = tm_min = tm_sec = 0;
  376.     }
  377.  
  378.     time = (tm_hour << 11) | (tm_min << 5) | (tm_sec >> 1);
  379.     date = ((tm_year - 80) & 0x7f) << 9;
  380.     date |= ((tm_mon) << 5) | (tm_mday);
  381.     return (time << 16) | date;
  382. }
  383.  
  384. /*
  385.  * Case insensitive string comparison. note that this only returns
  386.  * 0 (match) or nonzero (no match), and that the returned value
  387.  * is not a reliable indicator of any "order".
  388.  */
  389.  
  390. int ARGS_ON_STACK 
  391. strnicmp(str1, str2, len)
  392.     register const char *str1, *str2;
  393.     register int len;
  394. {
  395.     register char c1, c2;
  396.  
  397.     do {
  398.         c1 = *str1++; if (isupper(c1)) c1 = tolower(c1);
  399.         c2 = *str2++; if (isupper(c2)) c2 = tolower(c2);
  400.     } while (--len >= 0 && c1 && c1 == c2);
  401.  
  402.     if (len < 0 || c1 == c2)
  403.         return 0;
  404.     return c1 - c2;
  405. }
  406.  
  407. int ARGS_ON_STACK 
  408. stricmp(str1, str2)
  409.     const char *str1, *str2;
  410. {
  411.     return strnicmp(str1, str2, 0x7fff);
  412. }
  413.  
  414.  
  415. /*
  416.  * string utilities: strlwr() converts a string to lower case, strupr()
  417.  * converts it to upper case
  418.  */
  419.  
  420. char * ARGS_ON_STACK 
  421. strlwr(s)
  422.     char *s;
  423. {
  424.     char c;
  425.     char *old = s;
  426.  
  427.     while ((c = *s) != 0) {
  428.         if (isupper(c)) {
  429.             *s = _tolower(c);
  430.         }
  431.         s++;
  432.     }
  433.     return old;
  434. }
  435.  
  436. char * ARGS_ON_STACK 
  437. strupr(s)
  438.     char *s;
  439. {
  440.     char c;
  441.     char *old = s;
  442.  
  443.     while ((c = *s) != 0) {
  444.         if (islower(c)) {
  445.             *s = _toupper(c);
  446.         }
  447.         s++;
  448.     }
  449.     return old;
  450. }
  451.  
  452. #ifdef OWN_LIB
  453.  
  454. /*
  455.  * Case sensitive comparison functions.
  456.  */
  457.  
  458. int
  459. strncmp(str1, str2, len)
  460.     register const char *str1, *str2;
  461.     register int len;
  462. {
  463.     register char c1, c2;
  464.  
  465.     do {
  466.         c1 = *str1++;
  467.         c2 = *str2++;
  468.     } while (--len >= 0 && c1 && c1 == c2);
  469.  
  470.     if (len < 0) return 0;
  471.  
  472.     return c1 - c2;
  473. }
  474.  
  475. int
  476. strcmp(str1, str2)
  477.     const char *str1, *str2;
  478. {
  479.     register char c1, c2;
  480.  
  481.     do {
  482.         c1 = *str1++;
  483.         c2 = *str2++;
  484.     } while (c1 && c1 == c2);
  485.  
  486.     return c1 - c2;
  487. }
  488.  
  489.  
  490. /*
  491.  * some standard string functions
  492.  */
  493.  
  494. char *
  495. strcat(dst, src)
  496.     char *dst;
  497.     const char *src;
  498. {
  499.     register char *_dscan;
  500.  
  501.     for (_dscan = dst; *_dscan; _dscan++) ;
  502.     while ((*_dscan++ = *src++) != 0) ;
  503.     return dst;
  504. }
  505.  
  506. char *
  507. strcpy(dst, src)
  508.     char *dst;
  509.     const char *src;
  510. {
  511.     register char *_dscan = dst;
  512.     while ((*_dscan++ = *src++) != 0) ;
  513.     return dst;
  514. }
  515.  
  516. char *
  517. strncpy(dst, src, len)
  518.     char *dst;
  519.     const char *src;
  520.     int len;
  521. {
  522.     register char *_dscan = dst;
  523.     while (--len >= 0 && (*_dscan++ = *src++) != 0)
  524.         continue;
  525.     while (--len >= 0)
  526.         *_dscan++ = 0;
  527.     return dst;
  528. }
  529.  
  530. int
  531. strlen(scan)
  532.     const char *scan;
  533. {
  534.     register const char *_start = scan+1;
  535.     while (*scan++) ;
  536.     return (int)((long)scan - (long)_start);
  537. }
  538.  
  539. /*
  540.  * strrchr: find the last occurence of a character in a string
  541.  */
  542. char *
  543. strrchr(str, which)
  544.     const char *str;
  545.     register int which;
  546. {
  547.     register unsigned char c, *s;
  548.     register char *place;
  549.  
  550.     s = (unsigned char *)str;
  551.     place = 0;
  552.     do {
  553.         c = *s++;
  554.         if (c == which)
  555.             place = (char *)s-1;
  556.     } while (c);
  557.     return place;
  558. }
  559.  
  560. unsigned char _ctype[256] =
  561. {
  562.     _CTc, _CTc, _CTc, _CTc,                /* 0x00..0x03 */
  563.     _CTc, _CTc, _CTc, _CTc,                /* 0x04..0x07 */
  564.     _CTc, _CTc|_CTs, _CTc|_CTs, _CTc|_CTs,        /* 0x08..0x0B */
  565.     _CTc|_CTs, _CTc|_CTs, _CTc, _CTc,        /* 0x0C..0x0F */
  566.  
  567.     _CTc, _CTc, _CTc, _CTc,                /* 0x10..0x13 */
  568.     _CTc, _CTc, _CTc, _CTc,                /* 0x14..0x17 */
  569.     _CTc, _CTc, _CTc, _CTc,                /* 0x18..0x1B */
  570.     _CTc, _CTc, _CTc, _CTc,                /* 0x1C..0x1F */
  571.  
  572.     _CTs, _CTp, _CTp, _CTp,                /* 0x20..0x23 */
  573.     _CTp, _CTp, _CTp, _CTp,                /* 0x24..0x27 */
  574.     _CTp, _CTp, _CTp, _CTp,                /* 0x28..0x2B */
  575.     _CTp, _CTp, _CTp, _CTp,                /* 0x2C..0x2F */
  576.  
  577.     _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx,    /* 0x30..0x33 */
  578.     _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx,    /* 0x34..0x37 */
  579.     _CTd|_CTx, _CTd|_CTx, _CTp, _CTp,        /* 0x38..0x3B */
  580.     _CTp, _CTp, _CTp, _CTp,                /* 0x3C..0x3F */
  581.  
  582.     _CTp, _CTu|_CTx, _CTu|_CTx, _CTu|_CTx,        /* 0x40..0x43 */
  583.     _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, _CTu,        /* 0x44..0x47 */
  584.     _CTu, _CTu, _CTu, _CTu,                /* 0x48..0x4B */
  585.     _CTu, _CTu, _CTu, _CTu,                /* 0x4C..0x4F */
  586.  
  587.     _CTu, _CTu, _CTu, _CTu,                /* 0x50..0x53 */
  588.     _CTu, _CTu, _CTu, _CTu,                /* 0x54..0x57 */
  589.     _CTu, _CTu, _CTu, _CTp,                /* 0x58..0x5B */
  590.     _CTp, _CTp, _CTp, _CTp,                /* 0x5C..0x5F */
  591.  
  592.     _CTp, _CTl|_CTx, _CTl|_CTx, _CTl|_CTx,        /* 0x60..0x63 */
  593.     _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, _CTl,        /* 0x64..0x67 */
  594.     _CTl, _CTl, _CTl, _CTl,                /* 0x68..0x6B */
  595.     _CTl, _CTl, _CTl, _CTl,                /* 0x6C..0x6F */
  596.  
  597.     _CTl, _CTl, _CTl, _CTl,                /* 0x70..0x73 */
  598.     _CTl, _CTl, _CTl, _CTl,                /* 0x74..0x77 */
  599.     _CTl, _CTl, _CTl, _CTp,                /* 0x78..0x7B */
  600.     _CTp, _CTp, _CTp, _CTc,                /* 0x7C..0x7F */
  601.  
  602.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80..0x8F */
  603.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90..0x9F */
  604.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0..0xAF */
  605.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0..0xBF */
  606.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0..0xCF */
  607.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0..0xDF */
  608.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0..0xEF */
  609.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* 0xF0..0xFF */
  610. };
  611.  
  612. int toupper(c)
  613.     int c;
  614. {
  615.     return(islower(c) ? (c ^ 0x20) : (c));
  616. }
  617.  
  618. int tolower(c)
  619.     int c;
  620. {
  621.     return(isupper(c) ? (c ^ 0x20) : (c));
  622. }
  623.  
  624. /*
  625.  * converts a decimal string to an integer
  626.  */
  627.  
  628. long
  629. atol(s)
  630.     const char *s;
  631. {
  632.     long d = 0;
  633.     int negflag = 0;
  634.     int c;
  635.  
  636.     while (*s && isspace(*s)) s++;
  637.     while (*s == '-' || *s == '+') {
  638.         if (*s == '-')
  639.             negflag ^= 1;
  640.         s++;
  641.     }
  642.     while ((c = *s++) != 0 && isdigit(c)) {
  643.         d = 10 * d + (c - '0');
  644.     }
  645.     if (negflag) d = -d;
  646.     return d;
  647. }
  648.  
  649. #endif /* OWN_LIB */
  650.